package pe.gob.inei.fx.lib.component
{
	import mx.collections.ArrayCollection;
	import mx.containers.HBox;
	import mx.containers.VBox;
	import mx.controls.ButtonBar;
	import mx.controls.DataGrid;
	import mx.controls.HSlider;
	import mx.controls.Label;
	import mx.controls.Spacer;
	import mx.controls.dataGridClasses.DataGridColumn;
	import mx.events.CloseEvent;
	import mx.events.CollectionEvent;
	import mx.events.CollectionEventKind;
	import mx.events.ItemClickEvent;
	import mx.events.SliderEvent;
	import mx.managers.PopUpManager;
	
	import pe.gob.inei.fx.images.Icon;
	import pe.gob.inei.fx.lib.component.events.DispatcherEvent;
	import pe.gob.inei.fx.lib.component.events.ExporterEvent;
	import pe.gob.inei.fx.lib.component.events.ListCheckItemRendererEvent;
	import pe.gob.inei.fx.lib.component.events.TablaSliderEvent;

	[Event(name="exportar_a_excel", type="pe.gob.inei.fx.lib.component.events.ExporterEvent")]
	public class TablaSlider extends VBox {
		
		[Bindable]
		private var slider:HSlider;
		[Bindable]
		private var tabla:DataGrid;
		[Bindable]
		private var lbRango:Label;
		
		private var rangos:Array;
		
		private var dispatcher:DispatcherEvent = DispatcherEvent.instance(ListCheckItemRendererEvent);
		
		private var listCkeckIndicador:ListCheck;
		private var indicadoresSeleccionados:Number;
		private var bFiltroInd:Boolean;
		private var bFiltroPer:Boolean;
		private var bFiltroAmb:Boolean;
		
		private var tipoTabla:int;
		private var maxPeriodo:int;
		
		private var acNewData:ArrayCollection;
				
		/**********************************************************************************************
		 *                                        CONSTRUCTOR
		 ******************************************************************************************* */
		public function TablaSlider() {
			super();
			bFiltroInd = false;
			bFiltroPer = false;
			bFiltroAmb = false;
			
			var navega:HBox = new HBox();
			navega.setStyle("horizontalAlign", "right");
			navega.percentWidth = 100;
			
			lbRango = new Label();
			navega.addChild(lbRango);
			
			var space:Spacer = new Spacer();
			space.percentWidth = 100;
			navega.addChild(space);
			
			var excel:Object = new Object();
			excel.icon = Icon.generalIcons().excel;
			excel.toolTip = "Exportar a excel";
			
			var buttonBar:ButtonBar = new ButtonBar();
			buttonBar.dataProvider = [excel];
			buttonBar.addEventListener(ItemClickEvent.ITEM_CLICK, exportarClickEventHandler);
			navega.addChild(buttonBar);
			
			addChild(navega);
			
			slider = new HSlider();
			slider.percentWidth = 100;
			slider.thumbCount = 2;
			slider.snapInterval = 1;
			slider.tickInterval = 1;
			slider.showDataTip = true;
			slider.setStyle("dataTipPlacement", "bottom");
			slider.addEventListener(SliderEvent.CHANGE, filtrar);
			slider.liveDragging = true;
			addChild(slider);
			
			space = new Spacer();
			space.percentWidth = 100;
			addChild(space);
			tabla = new DataGrid();
			tabla.percentWidth = 100;
			tabla.percentHeight = 100;
			addChild(tabla);
			var controller:HBox = new HBox();
			controller.percentWidth = 100;
			
			var btnFiltro:ButtonBar = new ButtonBar();
			btnFiltro.addEventListener(ItemClickEvent.ITEM_CLICK, btnFiltroClickhandler);
			
			var _btnFiltroInd:Object = new Object();
			_btnFiltroInd.label = "Filtrar indicadores";
			var _btnFiltroPer:Object = new Object();
			_btnFiltroPer.label = "Filtrar periodos";
			var _btnFiltroAmb:Object = new Object();
			_btnFiltroAmb.label = "Filtrar ambitos";
			
			btnFiltro.dataProvider = [_btnFiltroInd, _btnFiltroPer, _btnFiltroAmb];
			controller.addChild(btnFiltro);
			
			addChild(controller);

			addEventListener(TablaSliderEvent.UPDATE_TABLA_SLIDER, updateTabla);
			addEventListener(TablaSliderEvent.UPDATE_DATA_TABLA_SLIDER, updateData);
			addEventListener(TablaSliderEvent.UPDATE_RANGO_TABLA_SLIDER, updateRango);
			
			dispatcher.addEventListener(ListCheckItemRendererEvent.CHECK_ITEM_SELECTED, checkItemSelectedHandler);
		}
		
		/**********************************************************************************************
		 *                                          PROPIEDADES
		 ******************************************************************************************* */
		
		private var _acData:ArrayCollection;
		
		[Bindable("collectionChange")]
		[Inspectable(category="Data", defaultValue="undefined")]
		public function set dataProvider(value:ArrayCollection):void {
			if(_acData)
				_acData.removeEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler);
			_acData = value;
			_acData.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler, false, 0, true);
			
			var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
			event.kind = CollectionEventKind.RESET;
			_acData.dispatchEvent(event);
			//BindingUtils.bindProperty(tabla, "dataProvider", this, "dataProvider");
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_TABLA_SLIDER, value));
		}
		
		public function set clickExporter(value:Function):void {
			addEventListener(ExporterEvent.EXPORTED_TO_EXCEL, value);
		}
		
		public function get dataProvider():ArrayCollection {
			return _acData;
		}
		
		private var _columnaPrincipal:String;
		
		public function set columnFiltro(value:String):void {
			_columnaPrincipal = value;
		}
		
		public function get columnFiltro():String {
			return _columnaPrincipal;
		}
		
		private var _ambitos:Array;
		
		public function set ambitos(values:Array):void {
			_ambitos = values;
		}
		
		public function get ambitos():Array {
			return _ambitos;
		}
		
		private var _nivUbigeo:int;
		
		public function set nivelUbigeo(value:int):void {
			_nivUbigeo = value;
		}
		
		public function get nivelUbigeo():int {
			return _nivUbigeo;
		}
		
		private var _acIndicadores:ArrayCollection;
		private var _acIndicadoresUF:ArrayCollection;
		
		[Bindable]
		public function set indicadores(values:ArrayCollection):void {
			_acIndicadores = values;
			_acIndicadoresUF = values;
		}
		
		public function get indicadores():ArrayCollection {
			return _acIndicadores;
		}
		
		private var _autoSave:Boolean;
		
		public function set autoSave(value:Boolean):void {
			_autoSave = value;
		}
		
		public function get autoSave():Boolean {
			return _autoSave;
		}
		
		private var _campoIndicador:String;
		
		public function set campoIndicador(value:String):void {
			_campoIndicador = value;
			listCkeckIndicador = new ListCheck("selected", "nombre_tema", value);
		}
		
		public function get campoIndicador():String {
			return _campoIndicador;
		}
		
		private var _ubigeos:ArrayCollection;
		
		public function set ubigeosFiltro(values:ArrayCollection):void {
			_ubigeos = values;
			var acFiltro:ArrayCollection = new ArrayCollection();
			if(nivelUbigeo > 0) {
				var idFiltro:String = (nivelUbigeo == 1?"id_dept":(nivelUbigeo == 2?"id_prov":"id_dist"));
				for(var i:String in _acData) {
					for(var j:int = 0; j < values.length; j++) {
						if(_acData[i][idFiltro] == values.list.getItemAt(j)){
							acFiltro.addItem(_acData[i]);
							break;
						}
					}
				}
			}
			else
				acFiltro = _acData;
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_DATA_TABLA_SLIDER, acFiltro));
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_TABLA_SLIDER, acFiltro));
		}
		
		public function get ubigeosFiltro():ArrayCollection {
			return _ubigeos;
		}
		
		/**********************************************************************************************
		 *                                            METODOS
		 ******************************************************************************************* */
		
		/**
		 * Relacional campos dinamicamente a selected y nombre_tema
		 * */
		private function filtroIndicador():void {
			if(bFiltroInd)
				return;
			bFiltroInd = true;
			var panel:SuperPanel = new SuperPanel();
			panel.allowClose = true;
			panel.allowResize = true;
			panel.allowDrag = true;
			panel.addEventListener(CloseEvent.CLOSE, function(event:CloseEvent):void {
				PopUpManager.removePopUp(panel);
				bFiltroInd = false;
			});
			panel.title = "Indicadores seleccionados - Tabla";
			panel.width = 450;
			panel.height = 200;
			var acDataProviderList:ArrayCollection = new ArrayCollection();
			var obj:Object = null;
			for(var i:String in _acIndicadores) {
				obj = new Object();
				obj = _acIndicadores[i];
				obj["selected"] = false;
				for(var j:String in _acIndicadoresUF) {
					if(obj[campoIndicador] == _acIndicadoresUF[j][campoIndicador]) {
						obj["selected"] = true;
						break;
					}
				}
				acDataProviderList.addItem(obj);
			}
			listCkeckIndicador.dataProvider = acDataProviderList;
			indicadoresSeleccionados = _acIndicadoresUF.length;
			panel.addChild(listCkeckIndicador);
			PopUpManager.addPopUp(panel, this);
			PopUpManager.centerPopUp(panel);
		}
		
		private function filtroPeriodo():void {
			if(bFiltroPer)
				return;
			bFiltroPer = true;
			var panel:SuperPanel = new SuperPanel();
			panel.allowClose = true;
			panel.allowResize = true;
			panel.allowDrag = true;
			panel.addEventListener(CloseEvent.CLOSE, function(event:CloseEvent):void {
				PopUpManager.removePopUp(panel);
				bFiltroPer = false;
			});
			panel.title = "Lista de periodos - Tabla";
			panel.width = 450;
			panel.height = 200;
			//listCkeckIndicador.dataProvider = acDataProviderList;
			//indicadoresSeleccionados = _acIndicadoresUF.length;
			//panel.addChild(listCkeckIndicador);
			PopUpManager.addPopUp(panel, this);
			PopUpManager.centerPopUp(panel);
		}
		
		private function filtroAmbito():void {
			if(bFiltroAmb)
				return;
			bFiltroAmb = true;
			var panel:SuperPanel = new SuperPanel();
			panel.allowClose = true;
			panel.allowResize = true;
			panel.allowDrag = true;
			panel.addEventListener(CloseEvent.CLOSE, function(event:CloseEvent):void {
				PopUpManager.removePopUp(panel);
				bFiltroAmb = false;
			});
			panel.title = "Lista de localidades - Tabla";
			panel.width = 450;
			panel.height = 200;
			//listCkeckIndicador.dataProvider = acDataProviderList;
			//indicadoresSeleccionados = _acIndicadoresUF.length;
			//panel.addChild(listCkeckIndicador);
			PopUpManager.addPopUp(panel, this);
			PopUpManager.centerPopUp(panel);
		}
		
		private function filtrarIndicadores(ac:Array, indicadoresList:ArrayCollection = null):void {
			var column:DataGridColumn = null;
			var nColumn:String = null;
			var newIndicadoresList:ArrayCollection = null;
			if(!autoSave)
				newIndicadoresList = _acIndicadores;
			else if(indicadoresList != null && indicadoresList.length > 0)
				_acIndicadoresUF = indicadoresList;
			newIndicadoresList = _acIndicadoresUF;
				
			for(var i:int; i < newIndicadoresList.length; i++) {
				nColumn = newIndicadoresList.list.getItemAt(i)[campoIndicador];
				column = new DataGridColumn(nColumn);
				column.dataField = nColumn;
				ac.push(column);
			}
		}
		
		private function crearTabla(filtroIndicadores:ArrayCollection = null):void {
			var ac:Array = new Array();
			//COLUMNA FIJA
			//addColumnFiltro(ac);
			//COLUMNAS DE UBIGEOS
			//addColumnsUbigeo(ac);
			//COLUMNAS DE INDICADORES
			//filtrarIndicadores(ac, filtroIndicadores);
			
			addColumnasFijas(ac);
			addColumnasDatos(ac);
			
			//COLUMNAS A LA TABLA
			tabla.columns = ac;
		}
		
		private function addColumnasFijas(ac:Array):void {
			var column:DataGridColumn = null;
			switch(tipoTabla) {
				case 1:
					column = new DataGridColumn("INDICADOR");
					column.dataField = "Indicador";
					ac.push(column);
					for(var i:int = 0; i < _nivUbigeo; i++) {
						column = new DataGridColumn((i==0?"DEPARTAMENTO":(i==1?"PROVINCIA":"DISTRITO")));
						column.dataField = _ambitos[i];
						ac.push(column);
					}
			}
		}
		
		private function addColumnasDatos(ac:Array):void {
			var column:DataGridColumn = null;
			switch(tipoTabla) {
				case 1:
					for(var i:int = 0; i <= maxPeriodo; i++) {
						column = new DataGridColumn(rangos[i]);
						column.dataField = rangos[i];
						ac.push(column);
					}
			}
		}
		
		private function addColumnFiltro(ac:Array):void {
			var column:DataGridColumn = new DataGridColumn(columnFiltro.toUpperCase());
			column.dataField = columnFiltro;
			ac.push(column);
		}
		
		private function addColumnsUbigeo(ac:Array):void {
			var column:DataGridColumn = null;
			for(var i:int = 0; i < _nivUbigeo; i++) {
				column = new DataGridColumn((i==0?"DEPARTAMENTO":(i==1?"PROVINCIA":"DISTRITO")));
				column.dataField = _ambitos[i];
				ac.push(column);
			}
		}
		
		private function crearSlider():void {
			slider.minimum = 0;
			slider.maximum = maxPeriodo;
			slider.setThumbValueAt(0, 0);
			slider.setThumbValueAt(1, maxPeriodo);
			slider.labels = [rangos[0], rangos[maxPeriodo]]
			slider.dataTipFormatFunction = showToolTip;
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_RANGO_TABLA_SLIDER, null, [0, maxPeriodo]));
		}
		
		private function showToolTip(value:String):String {
			return rangos[parseInt(value)];
		}
		
		private function determinarTipoTabla():void {
			var bInd:Boolean = (indicadores.length > 1);
			var bAmb:Boolean = true;
			var bPer:Boolean = true;
			if(bInd && bAmb && bPer)
				tipoTabla = 1;
			else if(!bInd && bAmb && bPer)
				tipoTabla = 2;
			else if(bInd && !bAmb && bPer)
				tipoTabla = 3;
			else if(bInd && bAmb && !bPer)
				tipoTabla = 4;
			else
				tipoTabla = 0;
		}
		
		private function get ubigeos():ArrayCollection {
			var sCampo:String = ambitos[nivelUbigeo - 1];
			var obj:Object = new Object();
			var sNombre:String = null;
			var acUbigeos:ArrayCollection = new ArrayCollection();
			var oUbigeo:Object = null;
			for(var i:String in dataProvider) {
				sNombre = dataProvider[i][sCampo];
				oUbigeo = new Object();
				if(obj[sNombre] == null) {
					obj[sNombre] = sNombre;
					for(var j:int = 0; j < nivelUbigeo; j++)
						oUbigeo[ambitos[j]] = dataProvider[i][ambitos[j]];
					acUbigeos.addItem(oUbigeo);
				}
			}
			return acUbigeos;
		}
		
		private function obtenerPeriodos(data:ArrayCollection):void {
			rangos = new Array();
			var max:Number = -1;
			var flag:Boolean = false;
			
			for(var i:String in data) {
				flag = false;
				for(var j:int = 0; j < rangos.length; j++)
					if(data[i][columnFiltro] == rangos[j])
						flag = true;
				if(!flag)
					rangos[++max] = data[i][columnFiltro];
			}
			maxPeriodo = max;
		}
		
		private function crearData():ArrayCollection {
			var sCampo:String = ambitos[nivelUbigeo - 1];
			var acnData:ArrayCollection = new ArrayCollection();
			var obj:Object = null;
			var flag:Boolean = true;
			for(var i:String in indicadores) {
				for(var j:String in ubigeos) {
					obj = new Object();
					obj["Indicador"] = indicadores[i].nombre_tema;
					for(var k:int = 0; k < nivelUbigeo; k++)
						obj[ambitos[k]] = ubigeos[j][ambitos[k]];
					for(var n:int = 0; n < rangos.length; n++) {
						/*for(var o:String in _acData) {
							for(var p:int = 0; p < nivelUbigeo; p++)
								flag = (flag && _acData[o][ambitos[p]] == obj[p])
							if(flag && _acData[o][columnFiltro] == rangos[n]) {
								Alert.show("aqui");
								obj[rangos[n]] = _acData[o][indicadores[i][campoIndicador]];
								break;
							}
						}*/
						obj[rangos[n]] = "*";
					}
					acnData.addItem(obj);
				}
			}
			return acnData;
		}
		
		private function set nuevaData(values:ArrayCollection):void {
			acNewData = values;
			
		}
		
		private function get nuevaData():ArrayCollection {
			return acNewData;
		}
		
		/**********************************************************************************************
		 *                                            EVENTOS
		 ******************************************************************************************* */
		
		private function collectionChangeHandler(event:CollectionEvent):void {
			determinarTipoTabla();
			obtenerPeriodos(_acData);
			nuevaData = crearData();
			tabla.dataProvider = nuevaData;
		}
		
		private function exportarClickEventHandler(event:ItemClickEvent):void {
			switch(event.index) {
				case 0:
					//EXCEL
					dispatchEvent(new ExporterEvent(ExporterEvent.EXPORTED_TO_EXCEL));
					break;
			}
		}
		
		private function btnFiltroClickhandler(event:ItemClickEvent):void {
			switch(event.index) {
				case 0: filtroIndicador(); break;
				case 1: filtroPeriodo(); break;
				case 2: filtroAmbito(); break;
			}
		}
		
		/**
		 * Definir variable dinamica para selected
		 * */
		private function checkItemSelectedHandler(event:ListCheckItemRendererEvent):void {
			if(indicadoresSeleccionados == 1 && !event.data["selected"]) {
				dispatcher.dispatchEvent(new ListCheckItemRendererEvent(ListCheckItemRendererEvent.MAX_SELECTED_QUIT + event.data[campoIndicador], event.data, event.objeto));
				return;
			}
			indicadoresSeleccionados = 0;
			var ac:ArrayCollection = new ArrayCollection();
			var objI:Object = null;
			var objJ:Object = null;
			for(var i:String in _acIndicadores) {
				objI = _acIndicadores[i];
				if(objI[campoIndicador] == event.data[campoIndicador] && event.data["selected"]) {
					ac.addItem(objI);
					indicadoresSeleccionados++;
					continue;
				}
				for(var j:String in _acIndicadoresUF) {
					objJ = _acIndicadoresUF[j];
					if(objJ[campoIndicador] == event.data[campoIndicador] && !event.data["selected"])
						continue;
					if(objI[campoIndicador] == objJ[campoIndicador]) {
						ac.addItem(objI);
						indicadoresSeleccionados++;
						break;
					}
				}
			}
			_acIndicadoresUF = ac;
			crearTabla(ac);
		}
		
		private function updateTabla(event:TablaSliderEvent):void {
			//Alert.show("Nueva-Data: " + event.dataProvider.length.toString());
			crearTabla();
			crearSlider();
		}
		
		private function updateData(event:TablaSliderEvent):void {
			tabla.dataProvider = event.dataProvider;
		}
		
		private function updateRango(event:TablaSliderEvent):void {
			var aSlider:Array = event.rangoSlider;
			lbRango.text = "RANGO ACTUAL: [" + rangos[aSlider[0]] + " A " + rangos[aSlider[1]] + "]";
		}
		
		private function filtrar(event:SliderEvent):void {
			var acFiltro:ArrayCollection = new ArrayCollection();
			var pFiltro:Array = new Array();
			var cont:Number = 0;
			var val:Array = slider.values;
			//OBTENER LOS PERIODOS FILTROS
			for(var x:int = parseInt(val[0]); x <= parseInt(val[1]); x++, cont++)
				pFiltro[cont] = rangos[x];
			//FILTRANDO LA TABLA
			for(var i:String in _acData) {
				for(var j:Number = 0; j < pFiltro.length; j++) {
					if(_acData[i][columnFiltro] == pFiltro[j]) {
						acFiltro.addItem(_acData[i]);
						break;
					}
				}
			}
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_DATA_TABLA_SLIDER, acFiltro, val));
			dispatchEvent(new TablaSliderEvent(TablaSliderEvent.UPDATE_RANGO_TABLA_SLIDER, acFiltro, val));
		}
	}
}